/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package br.com.marcio.obj;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
//import java.util.Vector;
import java.util.regex.Pattern;

public class OBJReader {

    public static Mesh readOBJ(String file) throws FileNotFoundException, IOException {
        BufferedReader in = new BufferedReader(new FileReader(file));
        Mesh m = new Mesh();

        // Pattern para split - tira todos espaços
        Pattern p = Pattern.compile("[ ]+");

        String linha = "";
        String materialName = "";
        int groupId = 0;
        int i = 0;
        while((linha = in.readLine()) != null) {
            try {
              
              i++;


              String[] args = linha.split(p.pattern());
              if(args[0].equals("mtllib")) {
//                Vector<Material> materials = MTLReader.readMTL("obj/" + args[1]);
//                for (Material material : materials)
//                  m.addMaterial(material);
            	  System.out.println("ignorando mtllib");
              }
              else if(args[0].equals("usemtl"))
//                  materialName = args[1];
            	  System.out.println("ignorando usemtl");
              else if(args[0].equals("v"))
                  m.addVertex(readVertex(args));
              else if(args[0].equals("vt"))
                  //m.addTextureMapping(readTextureMapping(args));
            	  System.out.println("vt - vetor textura ignorado");
              else if(args[0].equals("vn"))
                  m.addNormal(readVertex(args));
              else if(args[0].equals("g"))
                  m.addGroup(readGroup(args, ++groupId));
              else if(args[0].equals("f"))
                  m.addFace(readFace(args), materialName);
              else if(!(args[0].equals("") || args[0].equals("#")))
                  System.out.println(i + " - ignorou comando " + args[0]);

            } catch(NumberFormatException e) {
              System.out.println("Linha: " + i + " - " + linha);
              e.printStackTrace();
              System.exit(-1);
            } catch(IndexOutOfBoundsException e) {
              System.out.println("Linha: " + i + " - " + linha);
              e.printStackTrace();
              System.exit(-1);
            }
        }
        
        in.close();
        return m;
    }

    private static Vertex readVertex(String[] args) throws NumberFormatException {
        return new Vertex(
            Float.parseFloat(args[1]),
            Float.parseFloat(args[2]),
            Float.parseFloat(args[3])
        );
    }

//    private static TextureMapping readTextureMapping(String[] args) throws NumberFormatException {
//        return new TextureMapping(
//            Float.parseFloat(args[1]),
//            Float.parseFloat(args[2])
//        );
//    }

    private static Group readGroup(String[] args, int groupId) {
        // caso não seja passado um nome de grupo, criar como default
        if(args.length == 1)
            return new Group("default", groupId);
        return new Group(args[1], groupId);
    }

    private static int[][] readFace(String[] args) throws NumberFormatException {
        int sides = args.length - 1;
        int[] vertexes = new int[sides];
        int[] texturesMapping = new int[sides];
        int[] normals = new int[sides];

        for (int i = 1; i < args.length; i++) {
            String[] indexes = args[i].split("//");
            if(indexes.length != 1) {
                // formato v//n
                vertexes[i - 1] = Integer.parseInt(indexes[0]);
                texturesMapping[i - 1] = -1;
                normals[i - 1] = Integer.parseInt(indexes[1]);
            } else {
                indexes = args[i].split("/");
                if(indexes.length == 1) {
                    // formato v1 v2 v3
                    vertexes[i - 1] = Integer.parseInt(indexes[0]);
                    texturesMapping[i - 1] = -1;
                    normals[i - 1] = -1;

                }
                else if(indexes.length == 2) {
                    // formato v1/t1
                    vertexes[i - 1] = Integer.parseInt(indexes[0]);
                    texturesMapping[i - 1] = Integer.parseInt(indexes[1]);
                    normals[i - 1] = -1;
                } else {
                    // formato v1/t1/n1 v2/t2/n2 v3/t3/n3
                    vertexes[i - 1] = Integer.parseInt(indexes[0]);
                    texturesMapping[i - 1] = Integer.parseInt(indexes[1]);
                    normals[i - 1] = Integer.parseInt(indexes[2]);
                }
            }
        }
        return new int[][]{vertexes, texturesMapping, normals};
    }

}
